% Complete documentation on the extended LaTeX markup used for Python
% documentation is available in ''Documenting Python'', which is part
% of the standard documentation for Python.  It may be found online
% at:
%
%     http://www.python.org/doc/current/doc/doc.html

%labels
%Sections and subsections \label{sec: }
%Chapters \label{ch: }
%Equations \label{eq: }
%Figures \label{fig: }

\documentclass{manual}

\usepackage{graphicx}
\usepackage[english]{babel}
\usepackage{datetime}
\usepackage[hang,small,bf]{caption}

\input{definitions}

%%%%%
% Set penalties for widows, etc, very high
%%%%%

\widowpenalty=10000
\clubpenalty=10000
\raggedbottom

\title{pySlip User Manual}
\author{Ross Wilson}

% Please at least include a long-lived email address;
% the rest is at your discretion.
\authoraddress{
    Email: \email{rzzzwilson@gmail.com}
}

\longdate       % Make date format long using datetime.sty
%\settimeformat{oclock} % Verbose
\date{\today, \ \currenttime}

\ifhtml
    \date{\today} % latex2html does not know about datetime
\fi

\input{version}

\makeindex          % tell \index to actually write the .idx file
\makemodindex       % If this contains a lot of module sections.

\setcounter{tocdepth}{3}
\setcounter{secnumdepth}{3}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}
\maketitle

\input{copyright}

\tableofcontents

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Introduction}
\section{What is pySlip?}
pySlip started while I was writing Python code at Geoscience Australia.
It seemed that almost every application I was writing would benefit from a
'map view' to display and select things like hazard points along a coastline
or faults around an ocean.  But it was hard to display portions of a very
large image in a wxPython widget.  I had been writing small custom widgets for
wxPython so the idea was to write pySlip, a widget designed to have 
similar behaviour to the Google slip map or the
openstreetmap\footnote{http://wiki.openstreetmap.org/wiki/Slippy_Map} method of
displaying large images in a tiled manner.

It is a wxPython widget so doesn't live in a web browser. The tiles displayed
by the widget may come from anywhere (local disk, internet, etc). The initial
release will have a method of pre-generating map tiles using
GMT\footnote{http://gmt.soest.hawaii.edu/}.

pySlip uses a Cartesian coordinate system and cannot display anything like a
Mercator projection. This may change later.

The widget was designed as a component of a geophysical system, but could be
used by any application that needs to display large cartesian maps, such as
games.

The idea is that the widget should behave like Google maps:
\begin{itemize}
    \item Display very large maps;
    \item Move around the map by 'dragging';
    \item Zoom in and out; and
    \item Able to ornament a map with graphics depicting things like hazard
    points, faults, text, polygons, images, etc.
\end{itemize}

The tiled map data is pre-generated and is not computed on the fly.

%\label{sec:simpleexample}
%described in Chapter \ref{ch:getstarted}:
%\section{A Simple Example}
%\subsection{Outline of the Program}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newpage
\section{Internals}
pySlip presents information in a series of {\em layers}.  Layers are presented to
the user in what is called the {\em \zorder} in which layers are drawn sequentially
from bottom to top of the \zorder.  That means that data on a layer in the
\zorder may be covered by data in another layer higher in the \zorder.

The {\em map} layer displays the map tiles, is always present, and is always at
the bottom of the \zorder behind all the other layers.

User layers are created at the top of the \zorder but may be moved within the
\zorder by user code.

\subsection{Types of Layers}
Layers may be of various types:
\begin{itemize}
    \item Point layers
    \item Image layers
    \item Polygon layers
    \item Text layers
\end{itemize}

\subsubsection{Point Layers}
A point layer shows one or more points over the map.  The points may be of any
radius or colour.  User code may choose to be notified if the user clicks on or
near a point.

\subsubsection{Image Layers}
An image layer shows one or more images over the map.  User code may choose to
be notified if the user clicks on or near an image.

\subsubsection{Polygon Layers}
A polygon layer shows one or more polygons over the map.  The polygon lines may
be of a defined width and colour and the polygon may be filled with any other
colour.

\subsubsection{Text Layers}
A text layer shows one or more text strings and a position point on the map.
Each text string may be of any required size or colour.

\subsection{Map and View Relative Layers}
When defining a layer the user may decide to show the layer on top of the map
in the normally expected manner: when the map is dragged the layer moves with
the map.  This is called a {\bf map-relative} layer.  Object coordinates are 
given as a latitude and longitude.

Alternatively, the user may specify that a layer is drawn as
a {\bf view-relative} layer, where the layer objects do not move with the map
but stay fixed in the view.  Object coordinates in a map-relative are given
in pixels.

%\label{sec:simpleexample}
%described in Chapter \ref{ch:getstarted}:
%\section{A Simple Example}
%\subsection{Outline of the Program}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{pySlip API}
\label{ch:API}
This chapter describes the pySlip methods used within a wxPython application.
\section{Create a pyslip widget}
\begin{verbatim}
sm = pySlip(parent, tile_dir=None, start_level=None, min_level=None, max_level=None, **kwargs)
\end{verbatim} \\*
Returns a pySlip widget reference \verb!sm!.  The parameters are: \\*
\begin{tabular}{ l l }
\verb!parent!      & reference to the parent widget \\
\verb!tile_dir!    & path to a tile directory \\
\verb!start_level! & map level to show initially \\
\verb!min_level!   & minimum map level that will be displayed \\
\verb!max_level!   & maximum map level that will be displayed \\
\verb!kwargs!      & extra widget arguments passed to Panel superclass \\
\end{tabular}
\section{Layers}
\subsection{Add a point layer}
\begin{verbatim}
id = sm.add_point_layer(data, map_rel=True, name='<points_layer>', **kwargs)
\end{verbatim} \\*
Returns a layer handle \verb!id! which is used to identify the layer in all
future calls.  The parameters are: \\*
\begin{tabular}{ l l }
\verb!data!    & a list of Point data objects \\
\verb!map_rel! & whether map or view relative: True means map-relative \\
\verb!name!    & the text name of the layer (shows in debug) \\
\verb!kwargs!  & a dictionary of global layer parameters - see {\bf attributes} below \\
\end{tabular}

\verb!data! is an iterable of point data tuples \verb!(x, y, [attributes])! where
\verb!x! and \verb!y! are either map longitude and latitude or view pixel coordinates,
depending on \verb!map_rel!.  The optional \verb!attributes! dictionary contains
point-specific attributes that override the layer global attributes.  See
{\bf attributes} below for more details.

The attributes that apply to a point layer are: \\*
\begin{tabular}{ l l }
\verb!radius! & sets the radius in pixels of the drawn point \\
\verb!colour! & sets the colour of the drawn point \\
\end{tabular}
\subsection{Add a polygon layer}
\begin{verbatim}
id = sm.add_polygon_layer(data, map_rel=True, name='<polygon_layer>', **kwargs)
\end{verbatim}

Returns the polygon layer handle \verb!id!.  The parameters are: \\*
\begin{tabular}{ l l }
\verb!data!    & a list of polygon data objects \\
\verb!map_rel! & whether map or view relative: True means map-relative \\
\verb!name!    & the text name of the layer (shows in debug) \\
\verb!kwargs!  & a dictionary of global layer parameters - see {\bf attributes} below \\
\end{tabular}

\verb!data! is an iterable of polygon data tuples \verb!(points, [attributes])! where
\verb!points! is an iterable of \verb!(x, y)! tuples where \verb!x! and \verb!y! are
either map longitude and latitude or view pixel coordinates, depending on
\verb!map_rel!.  The optional \verb!attributes! dictionary contains
polygon-specific attributes that override the layer global attributes.
See {\bf attributes} below for more details.

The attributes that apply to a polygon layer are: \\*
\begin{tabular}{ l l }
\verb!width!      & sets the width in pixels of the drawn polygon \\
\verb!colour!     & sets the colour of the polygon outline \\
\verb!close!      & a boolean that indicates if the polygon should be closed (if True) \\
\verb!filled!     & a boolean that indicates if the polygon should be filled (if True) \\
\verb!fillcolour! & sets the polygon fill colour \\
\end{tabular}
\subsection{Add an image layer}
\begin{verbatim}
id = sm.add_image_layer(data, map_rel=MAP_RELATIVE, name='<image_layer>', **kwargs)
\end{verbatim}
Returns the image layer handle \verb!id!.  The parameters are: \\*
\begin{tabular}{ l l }
\verb!data!    & an iterable of image data objects \\
\verb!map_rel! & whether map or view relative: True means map-relative \\
\verb!name!    & the text name of the layer (shows in debug) \\
\verb!kwargs!  & a dictionary of global layer parameters - see {\bf attributes} below \\
\end{tabular}

\verb!data! is an iterable of image data tuples \verb!(x, y, fname, [attributes])!
where \verb!x! and \verb!y! are either map longitude and latitude or view pixel
coordinates, depending on \verb!map_rel!.  \verb!fname! is the path to the file
containing the image to display.  The optional \verb!attributes! dictionary
contains image-specific attributes that override the layer global attributes.
See {\bf attributes} below for more details.

The attributes that apply to an image layer are: \\*
\begin{tabular}{ l l }
\verb!placement! & a string describing the image placement \\
\verb!offset_x!  & X direction offset from placement point \\
\verb!offset_y!  & Y direction offset from placement point \\
\verb!radius!    & radius in pixels of the image hotspot point, 0 means don't draw \\
\verb!colour!    & colour of the hotspot, if drawn \\
\end{tabular}

For more information about placement see the {\bf placement} section below.
\subsection{Add a text layer to a pySlip instance}
\begin{verbatim}
id = sm.add_text_layer(data, map_rel=MAP_RELATIVE, name='<image_layer>', **kwargs)
\end{verbatim} \\*
Returns the text layer handle.  The parameters are: \\*
\begin{tabular}{ l l }
\verb!data!    & an iterable of text data objects \\
\verb!map_rel! & whether map or view relative: True means map-relative \\
\verb!name!    & the text name of the layer (shows in debug) \\
\verb!kwargs!  & a dictionary of global layer parameters - see {\bf attributes} below \\
\end{tabular}

\verb!data! is an iterable of text data tuples \verb!(x, y, text, [attributes])! where
\verb!x! and \verb!y! are either map longitude and latitude or view pixel coordinates,
depending on \verb!map_rel!.  \verb!text! is the text string to display.  The optional
\verb!attributes! dictionary contains text-specific attributes that override the
layer global attributes.  See {\bf attributes} below for more details.

The attributes that apply to a text layer are: \\*
\begin{tabular}{ l l }
\verb!placement! & a string describing the text placement \\
\verb!offset_x!  & X direction offset from placement point \\
\verb!offset_y!  & Y direction offset from placement point \\
\verb!radius!    & radius in pixels of the text hotspot point, 0 means don't draw \\
\verb!colour!    & colour of the hotspot, if drawn \\
\verb!fontname!  & name of font family to render text string \\
\verb!fontsize!  & size of font used to render text string \\
\end{tabular}

For more information about placement see the {\bf placement} section below.

\section{Layer manipulation}
\subsection{Show a layer}
\begin{verbatim}
sm.show_layer(id)
\end{verbatim} \\*
Shows the layer identified by \verb!id!. \\*
\subsection{Hide a layer}
\begin{verbatim}
sm.hide_layer(id)
\end{verbatim} \\*
Hide the layer identified by \verb!id!.
\subsection{Delete a layer}
\begin{verbatim}
sm.delete_layer(id)
\end{verbatim} \\*
Delete the layer identified by \verb!id!.
\subsection{Push a layer to the back of the display Z order}
\begin{verbatim}
sm.push_layer_to_back(id)
\end{verbatim} \\*
Push the layer identified by \verb!id! to the back of the \zorder,
just above the map layer.
\subsection{Pop a layer to the front of the display Z order}
\begin{verbatim}
sm.pop_layer_to_front(id)
\end{verbatim} \\*
Pop the layer identified by \verb!id! to the top of the \zorder in front
of all other layers.
\subsection{Move a layer behind another layer}
\begin{verbatim}
sm.place_layer_below_layer(self, id, top_id)
\end{verbatim} \\*
Place the layer identified by \verb!id! to just behind layer
\verb!top_id! in the \zorder.
\section{Zoom and Pan Functions}
\subsection{Zoom to a Map Level}
\begin{verbatim}
sm.zoom_to_level(self, level)
\end{verbatim} \\*
Zoom in or out to the required map \verb!level!.
\subsection{Pan to the given position in the current map zoom level}
\begin{verbatim}
sm.goto_position(posn)
\end{verbatim} \\*
If possible, move the map layer such that the centre of the map is at
\verb!posn! which is a tuple \verb!(longitude, latitude)!.
\subsection{Zoom to a map level and pan to the given position in the map}
\begin{verbatim}
sm.goto_level_and_position(level, posn)
\end{verbatim} \\*
Change the map level to \verb!level! and then, if possible, move the map layer
such that the centre of the map is at \verb!posn! which is a tuple
\verb!(longitude, latitude)!.
\subsection{Zoom to a map level and pan to a position such that the specified area is completely within the view}
\begin{verbatim}
sm.zoom_to_area(posn, size)
\end{verbatim} \\*
Given a \verb!size! tuple \verb!(width, height)! of an area in
degrees, change to a map level that can completely show the area and centre the
view on \verb!posn!  which is a tuple of \verb!(longitude, latitude)!.

----
==pySlip Events==

The pySlip widget raises events when certain things happen in the widget.  The events are:

|| {{{EVT_PYSLIP_LEVEL}}} || Raised when the tile layer level changes. ||
|| {{{EVT_PYSLIP_POSITION}}} || Raised when the mouse position on the map changes. ||
|| {{{EVT_PYSLIP_SELECT}}} || Raised when zero or more objects are selected in a layer. ||

=={{{EVT_PYSLIP_LEVEL}}}==

This event is raised when the level of the map tiles changes.  The event attributes are:

|| {{{event.level}}} || The new map tile level. ||

=={{{EVT_PYSLIP_POSITION}}}==

This event is raised whenever the mouse moves over the tile map.  The event attributes are:

|| {{{event.position}}} || A tuple of the current mouse position - {{{(lon, lat)}}}. ||

=={{{EVT_PYSLIP_SELECT}}}==

This event is raised whenever the user attempts to select one or more objects in a layer.  The event attributes are:

|| {{{event.type}}} || The type of select, either {{{pyslip.EventPointSelect}}} or {{{pyslip.EventBoxSelect}}}. ||
|| {{{event.layer_id}}} || The ID of the layer the selected object(s) are in. ||
|| {{{event.point}}} || For a {{{EventPointSelect}}} event this is either {{{None}}} (no points selected) or a tuple {{{(lon, lat)}}} of the selected point.  For a {{{EventBoxSelect}}} event it is either an empty list (nothing selected) or a list of {{{(lon, lat)}}} coordinates of selected objects. ||


----

==Placement==

A _placement_ attribute is used when positioning layer objects in the
view-relative mode.  The {{{placement}}} attribute is supplied either on the
layer creation call as a global attribute or is applied to each layer object
directly.

The {{{placement}}} attribute is a string describing where in the view each
object is to be displayed.  The strings and the view-relative positions
the strings indicate are shown below:

{{{
    +------------------------------------------------------+
    |nw                        cn                        ne|
    |                                                      |
    |                                                      |
    |                                                      |
    |                                                      |
    |                                                      |
    |cw                        cc                        ce|
    |                                                      |
    |                                                      |
    |                                                      |
    |                                                      |
    |                                                      |
    |sw                        cs                        se|
    +------------------------------------------------------+
}}}

The placement strings can be remembered in the following way:

|| cc  || centre of the view ||
|| ne  || north-east corner ||
|| ce  || centre-east edge ||
|| se  || south-east corner ||
|| cs  || centre-south edge ||
|| sw  || south-west corner ||
|| cw  || centre-west edge ||
|| nw  || north-west corner ||
|| cn  || centre-north edge ||

The actual position where a layer object is placed depends on the placement
string and the coordinates defined for the layer object.  The placement string
defines the coordinate origin for the object and the point on the object which
is placed relative to the origin.  The object coordinates specify the position
of the point on the object with respect to the origin.

For example, a placement string {{{'ne'}}} specifies that the origin for
object placement is at the top-right corner of the view and that the point
on the object used to place it is the top-right corner.  The object coordinates
specify the position of the object point from the origin.

Pixel coordinates are the usual graphics setup: the positive X coordinates
are to the right of the origin and positive Y coordinates are below the
origin.

For example, a text object with a {{{'cs'}}} placement and coordinates
{{{(0,-10)}}} will have the centre of its bottom edge placed 10 pixels above
the centre of the bottom view edge.

----

==Object Attributes==

Objects in a layer have _attributes_ such as *placement*, *colour* and *offsets*.  Different types of objects may have different sets of attributes.

===Specifying Attributes===

pySlip has global defaults for all attributes - if you don't specify a colour for a point, say, then the global default colour will be applied to the point.

You may specify a layer default for any attribute when you create the layer.  This attribute value applies rather than the global default.  See the API calls to add layers to pySlip above.

Alternatively, you can specify a specific attribute value for every object in a layer by adding an attribute dictionary to each object in the data supplied to an API call to add a layer.

Individual attribute values override layer attribute values, which in turn override the global default attributes.

===Global Point Default Attributes===

The global default attribute values for a point layer are:

|| {{{placement}}} || 'nw' ||
|| {{{radius}}} || 3 ||
|| {{{colour}}} || 'red' ||
|| {{{offset_x}}} || 0 ||
|| {{{offset_y}}} || 0 ||


The global default attribute values for an image layer are:

|| {{{placement}}} || 'cc' ||
|| {{{radius}}} || 0 ||
|| {{{colour}}} || 'black' ||
|| {{{offset_x}}} || 0 ||
|| {{{offset_y}}} || 0 ||


The global default attribute values for a polygon layer are:

|| {{{placement}}} || 'cc' ||
|| {{{width}}} || 1 ||
|| {{{colour}}} || 'red' ||
|| {{{close}}} || False ||
|| {{{filled}}} || False ||
|| {{{fillcolour}}} || 'blue' ||
|| {{{offset_x}}} || 0 ||
|| {{{offset_y}}} || 0 ||


The global default attribute values for a text layer are:

|| {{{placement}}} || 'se' ||
|| {{{radius}}} || 2 ||
|| {{{colour}}} || 'black' ||
|| {{{offset_x}}} || 5 ||
|| {{{offset_y}}} || 1 ||
|| {{{fontname}}} || 'Arial' ||
|| {{{fontsize}}} || 9 ||

%\label{sec:simpleexample}
%described in Chapter \ref{ch:getstarted}:
%\section{A Simple Example}
%\subsection{Outline of the Program}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{pySlip Example}
\label{ch:example}

This chapter describes the pySlip methods used within a wxPython application.

%\label{sec:simpleexample}
%described in Chapter \ref{ch:getstarted}:
%\section{A Simple Example}
%\subsection{Outline of the Program}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Installing pySlip}
\label{ch:installing}

This chapter describes how to install pySlip.

%\label{sec:simpleexample}
%described in Chapter \ref{ch:getstarted}:
%\section{A Simple Example}
%\subsection{Outline of the Program}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\appendix

\chapter{Supporting Tools}
\label{ch:supportingtools}

This section describes a number of supporting tools, supplied with pySlip,
that offer a variety of types of functionality and can enhance the basic
capabilities of pySlip.

\section{Tile Generation}
\label{sec:tile_generation}

The \code{cache} function is used to provide supervised caching of function
results. A Python function call of the form:

\begin{verbatim}
result = func(arg1, ..., argn)
\end{verbatim}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\end{document}
